<template>
  <div :class="['box clearfix', (imgLength < max && !disabled) ? '' : 'unUpload']">
    <div class="el-upload-list__item" v-for="(item, index) in imgFileList" :key="index">
      <img :src="item.url" class="el-upload-list__item-thumbnail" />
      <span class="el-upload-list__item-actions">
        <span class="el-upload-list__item-do" @click="handlePictureCardPreview(imgFileList, index)">
          <i class="el-icon-zoom-in"></i>
        </span>
        <span class="el-upload-list__item-do" @click="handleDownload(item)">
          <i class="el-icon-download"></i>
        </span>
        <span class="el-upload-list__item-do" v-if="!disabled" @click="handleRemove(item, index)">
          <i class="el-icon-delete"></i>
        </span>
      </span>
    </div>
    <el-upload ref="uploadImg" :file-list="imgFileList" :show-file-list="false" :accept="accept" :action="uploadUrl"
      :on-change="imgChange" v-on="$listeners" v-bind="$attrs" list-type="picture-card" :auto-upload="autoUploadImg">
      <i slot="default" class="el-icon-plus"></i>
    </el-upload>
    <cropper ref="myCropper" :setting="options" :loading.sync="loading" @getFile="getFile" @upAgain="upAgain"></cropper>
  </div>
</template>

<script>
import { compress } from "@/utils/compress-img.js"
import cropper from "@/components/cropper-img/index.vue"
export default {
  name: "XiaobuUploadImg",
  components: {
    cropper
  },
  props: {
    // 是否开启压缩
    isCompress: {
      type: Boolean,
      default: true
    },
    // disabled
    disabled: {
      type: Boolean,
      default: false
    },
    // 是否开启裁剪
    openCropper: {
      type: Boolean,
      default: false
    },
    // 裁剪的配置
    options: {
      type: Object,
      default: () => {
        return {}
      }
    },
    acceptTips: {
      type: String,
      default: "请上传正确格式图片"
    },
    accept: {
      type: String,
      default: ".jpg,.png,.jpeg,.gif"
    },
    max: {
      type: Number,
      default: 3
    },
    autoUploadImg: {
      type: Boolean,
      default: false
    },
    uploadUrl: {
      type: String,
      default: "#"
    },
    imgList: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  watch: {
    imgList: {
      handler: function(val) {
        this.imgLength = val.length
        this.imgFileList = val
      },
      deep: true,
      immediate: true
    }
  },
  data() {
    return {
      loading: false, //上传图片按钮加载状态
      dialogImageUrl: "", //图片URL
      imgFileList: [], // 文件列表
      imgLength: 0
    }
  },
  mounted() {
    this.imgLength = this.imgList.length
  },
  methods: {
    /**
     * @description: 确定上传
     * @param {*} file
     * @return {*}
     * @author: syx
     */
    getFile(file) {
      const url = window.URL.createObjectURL(file)
      this.imgFileList.push({
        name: file.name,
        url,
        raw: file
      })
      this.loading = false

      if (this.openCropper) {
        //上传成功后，关闭弹框组件
        this.$refs.myCropper.close()
      }

      this.$nextTick(() => {
        this.imgLength = this.imgFileList.length
        this.$emit("imgChange", this.imgFileList)
      })
    },
    // 点击弹框重新上传时触发
    upAgain() {
      this.$refs["uploadImg"].$refs["upload-inner"].handleClick()
    },
    /**
     * @description: 移除图片
     * @param {*} file
     * @return {*}
     * @author: syx
     */
    handleRemove(file, index) {
      this.imgFileList.splice(index, 1)
      this.$nextTick(() => {
        this.imgLength = this.imgFileList.length
        this.$emit("imgChange", this.imgFileList)
      })
    },
    /**
     * @description: 预览图片
     * @param {*} file
     * @return {*}
     * @author: syx
     */
    handlePictureCardPreview(fileList, index) {
      const imgList = fileList.map(item => { return item.url })
      if (imgList.length === 1) {
        this.$xiaobuImgPreview({
          url: imgList[0]
        })
      } else {
        this.$xiaobuImgPreview({
          multiple: true, // 开启多图预览模式
          nowImgIndex: index, // 多图预览，
          imgList: imgList // 需要预览的多图数组
        })
      }
    },
    /**
     * @description: 下载文件
     * @param {*} file
     * @return {*}
     * @author: syx
     */
    handleDownload(file) {
      this.downloadByUrl(file.url, file.name)
    },
    /**
     * @description: 图片改变
     * @param {*}
     * @return {*}
     * @author: syx
     */
    async imgChange(file) {

      // 修复一次性 上传多张时  max配置无效的bug
      const imgLength = this.$refs.uploadImg.uploadFiles.length
      if (file && imgLength > this.max) {
        this.handleRemove(file)
        return
      }

      if (file && file.name) {
        const nameArray = file.name.split(".")
        const suffix = file.name.split(".")[nameArray.length - 1]
        if (this.accept.indexOf(suffix) === -1) {
          this.$modal.msgError(this.acceptTips)
          return
        }
      }

      // 开启压缩图片
      if (this.isCompress) {
        const newFile = await compress(file.raw)
        file.raw = newFile
      }

      // 开启裁剪
      if (this.openCropper) {
        this.handleCrop(file)
      } else {
        this.getFile(file.raw)
      }
    },
    /**
     * @description: 触发图片裁减
     * @param {*} file
     * @return {*}
     * @author: syx
     */
    handleCrop(file) {
      this.$nextTick(() => {
        this.$refs.myCropper.open(file.raw || file)
      })
    },
    /**
     * @description: 获取图片列表
     * @param {*}
     * @return {*}
     * @author: syx
     */
    getImgList() {
      return this.imgFileList
    },
    /**
     * @description: 清空图片列表
     * @param {*}
     * @return {*}
     * @author: syx
     */
    removeImgList() {
      if (this.imgFileList.length === 0) { return }
      this.imgFileList = []
      this.$nextTick(() => {
        this.$emit("imgChange", this.imgFileList)
      })
    },
    /**
     * @description: 通过URL下载图片
     * @param {*}
     * @return {*}
     * @author: syx
     */
    async downloadByUrl(url, name) {
      var base64Data = await this.convertUrlToBase64(url)
      this.downloadByBase64(base64Data, name)
    },
    /**
     * @description: 将URL转化为base64
     * @param {*} url
     * @return {*}
     * @author: syx
     */
    convertUrlToBase64(url) {
      return new Promise(function(resolve, reject) {
        var img = new Image()
        img.crossOrigin = "Anonymous"
        img.src = url
        img.onload = function() {
          var canvas = document.createElement("canvas")
          canvas.width = img.width
          canvas.height = img.height
          var ctx = canvas.getContext("2d")
          ctx.drawImage(img, 0, 0, img.width, img.height)
          var ext = img.src
            .substring(img.src.lastIndexOf(".") + 1)
            .toLowerCase()
          var dataURL = canvas.toDataURL("image/" + ext)
          resolve(dataURL)
        }
        img.onerror = function(e) {
          reject(e)
        }
      })
    },
    /**
     * @description: 通过base64下载图片
     * @param {*} base64Data
     * @param {*} name
     * @return {*}
     * @author: syx
     */
    downloadByBase64(base64Data, name) {
      var blob = this.convertBase64UrlToBlob(base64Data) // 转为blob对象
      // 下载
      if (this.myBrowser() === "IE") {
        window.navigator.msSaveBlob(blob, name)
      } else if (this.myBrowser() === "FF") {
        window.location.href = base64Data
      } else {
        var a = document.createElement("a")
        a.download = name
        a.href = URL.createObjectURL(blob)
        a.click()
      }
    },
    /**
     * @description: base64转化为 blob流
     * @param {*} base64
     * @return {*}
     * @author: syx
     */
    convertBase64UrlToBlob(base64) {
      var parts = base64.split(";base64,")
      var contentType = parts[0].split(":")[1]
      var raw = window.atob(parts[1])
      var rawLength = raw.length
      var uInt8Array = new Uint8Array(rawLength)
      for (var i = 0; i < rawLength; i++) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      return new Blob([uInt8Array], { type: contentType })
    },
    /**
     * @description: 浏览器判断
     * @param {*}
     * @return {*}
     * @author: syx
     */
    myBrowser() {
      var userAgent = navigator.userAgent //取得浏览器的userAgent字符串
      if (userAgent.indexOf("OPR") > -1) {
        return "Opera"
      } //判断是否Opera浏览器 OPR/43.0.2442.991
      if (userAgent.indexOf("Firefox") > -1) {
        return "FF"
      } //判断是否Firefox浏览器  Firefox/51.0
      if (userAgent.indexOf("Trident") > -1) {
        return "IE"
      } //判断是否IE浏览器 Trident/7.0 rv:11.0
      if (userAgent.indexOf("Edge") > -1) {
        return "Edge"
      } //判断是否Edge浏览器 Edge/14.14393
      if (userAgent.indexOf("Chrome") > -1) {
        return "Chrome"
      } // Chrome/56.0.2924.87
      if (userAgent.indexOf("Safari") > -1) {
        return "Safari"
      } //判断是否Safari浏览器 AppleWebKit/534.57.2 Version/5.1.7 Safari/534.57.2
    }
  }
}
</script>

<style lang="scss" scoped>
//结果样本
.unUpload ::v-deep .el-upload--picture-card {
  display: none;
}

.img-box {
  width: 100%;
  height: 100%;
  position: relative;

  .upload-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    vertical-align: middle;
  }
}

.el-upload-list__item {
  width: 148px;
  height: 148px;
  float: left;
  margin: 0;
  margin-right: 10px;
  margin-bottom: 10px;
  position: relative;
  border-radius: 4px;
  overflow: hidden;

  .el-upload-list__item-thumbnail {
    width: 100%;
    height: 100%;
    vertical-align: middle;
  }

  .el-upload-list__item-actions {
    position: absolute;
    display: none;
    opacity: 0;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    transition: all 0.36s;
    justify-content: center;
    align-items: center;

    .el-upload-list__item-do {
      color: #fff;
      cursor: pointer;

      .el-icon-zoom-in,
      .el-icon-download,
      .el-icon-delete {
        font-size: 24px;
      }

      &+.el-upload-list__item-do {
        margin-left: 20px;
      }
    }
  }

  &:hover {
    .el-upload-list__item-actions {
      display: flex;
      opacity: 1;
    }
  }
}
</style>
